package com.lechuang.thread.config;

import com.lechuang.thread.properties.ThreadProperties;
import lombok.extern.log4j.Log4j2;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * <p>
 *
 * </p>
 * @author liaoningbo
 * @since 2023/6/7
*/
@Configuration
@Log4j2
public class ThreadConfig {
    /**
     * <p>
     *   注入配置文件
     * </p>
     * @author liaoningbo
     * @since 2023/5/30
     */
    @Bean
    @ConditionalOnMissingBean
    public ThreadProperties threadProperties() {
        return new ThreadProperties();
    }

    /**
     * 创建 ThreadPoolTaskExecutor对象
     * @param threadProperties ThreadPoolTaskExecutor配置
     * @return ThreadPoolTaskExecutor
     */
    @Bean
    @Primary
    @ConditionalOnProperty(prefix = "thread", name = "enable")
    public ThreadPoolTaskExecutor createThreadPoolTaskExecutor(final ThreadProperties threadProperties) {
        log.info("==== 初始化线程池 ==== corePoolSize:{}, maxPoolSize:{}, queueCapacity:{}, keepAlive:{}", threadProperties.getCorePoolSize(), threadProperties.getMaxPoolSize(), threadProperties.getQueueCapacity(), threadProperties.getKeepAlive());
        ThreadPoolTaskExecutor threadPoolTaskExecutor =  new ThreadPoolTaskExecutor();
        threadPoolTaskExecutor.setCorePoolSize(threadProperties.getCorePoolSize());
        threadPoolTaskExecutor.setMaxPoolSize(threadProperties.getMaxPoolSize());
        threadPoolTaskExecutor.setKeepAliveSeconds(threadProperties.getKeepAlive());
        threadPoolTaskExecutor.setQueueCapacity(threadProperties.getQueueCapacity());
        threadPoolTaskExecutor.setThreadFactory(Executors.defaultThreadFactory());
        threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        threadPoolTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        threadPoolTaskExecutor.setTaskDecorator(new MDCTaskDecorator());
        threadPoolTaskExecutor.initialize();
        return threadPoolTaskExecutor;
    }
}
